import contextvars
import json
from fastapi import Request
from loguru import logger
import uuid
from starlette.middleware.base import BaseHTTPMiddleware

# 唯一请求 ID 的上下文变量
# FastAPI 会自动管理这些上下文变量的生命周期
request_id_context = contextvars.ContextVar("request_id", default="-")


class HttpMiddleware(BaseHTTPMiddleware):
    """为每一个HTTP请求生成唯一requestId
    """
    async def dispatch(self, request: Request, call_next):
        request_id = str(uuid.uuid4())
        request_id_context.set(request_id)

        method = request.method
        path = request.url.path

        with logger.contextualize(request_id=request_id):
            logger.info(f"Request started: \"{method} {path}\"")

            # 打印 GET 请求参数
            if method == "GET":
                query_params = request.query_params
                if query_params:
                    logger.info(f"Query parameters: {query_params}")

            # 如果是 POST/PUT 请求，获取请求体
            elif method in ["POST", "PUT"]:
                content_type = request.headers.get("Content-Type")
                if "multipart/form-data" in content_type:
                    logger.info(f"Request Content-Type: {content_type}")
                elif "application/json" in content_type:
                    body = await request.json() if request.method in ["POST", "PUT"] else None
                    logger.info(f"Request body: {json.dumps(body, ensure_ascii=False)}")

            try:
                response = await call_next(request)
                return response
            except Exception as ex:
                # logger.error(f"Request failed: {ex} {traceback.format_exc()}")
                raise ex
